#ifndef GB28181_INVITE_H
#define GB28181_INVITE_H

#include <string>
#include <memory>
#include <functional>
#include <chrono>

extern "C" {
#include <eXosip2/eXosip.h>
#include <osipparser2/osip_message.h>
}

namespace El {
namespace GB28181 {

// Forward declarations
struct SipServerConfig;

// Media session info
struct MediaSession {
    std::string session_id;
    std::string channel_id;
    std::string ssrc;
    std::string client_ip;
    int client_port;
    std::string local_ip;
    int local_port;
    bool is_tcp;
    std::chrono::steady_clock::time_point start_time;
    
    MediaSession() : client_port(0), local_port(0), is_tcp(false) {}
};

// INVITE handler for real-time video streaming
class GB28181Invite {
public:
    using MediaSessionCallback = std::function<void(const MediaSession& session, bool started)>;
    
    // Process incoming INVITE request for real-time video
    static void ProcessInviteRequest(eXosip_event_t *event, eXosip_t *exosip_context,
                                   const SipServerConfig &config,
                                   MediaSessionCallback sessionCallback);
    
    // Process BYE request to stop video streaming
    static void ProcessByeRequest(eXosip_event_t *event, eXosip_t *exosip_context,
                                const SipServerConfig &config,
                                MediaSessionCallback sessionCallback);
    
    // Send 200 OK response with SDP for INVITE
    static void SendInviteOk(eXosip_t *exosip_context, eXosip_event_t *event,
                           const MediaSession &session);
    
    // Send 200 OK response for BYE
    static void SendByeOk(eXosip_t *exosip_context, eXosip_event_t *event);
    
    // Parse INVITE SDP to extract media info
    static bool ParseInviteSDP(const std::string &sdp_content, MediaSession &session);
    
    // Create SDP response for INVITE OK
    static std::string CreateResponseSDP(const MediaSession &session);
    
    // Extract channel ID from INVITE URI
    static std::string ExtractChannelId(osip_message_t *message);
    
    // Generate SSRC for RTP stream
    static std::string GenerateSSRC(const std::string &channel_id);
    
    // Find available local port for RTP
    static int FindAvailablePort(int start_port = 10000);
    
    // Get local IP address
    static std::string GetLocalIP();

private:
    // Parse SDP attribute line
    static bool ParseSDPAttribute(const std::string &line, const std::string &attr, std::string &value);
    
    // Parse SDP media line
    static bool ParseSDPMedia(const std::string &line, std::string &media_type, int &port, std::string &protocol);
    
    // Parse SDP connection line
    static bool ParseSDPConnection(const std::string &line, std::string &network_type, 
                                 std::string &address_type, std::string &address);
};

} // namespace GB28181
} // namespace El

#endif // GB28181_INVITE_H